home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / gold / smallMethods.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.6 KB  |  359 lines

  1. /*
  2.  * The original copyright owners of the accompanying source code files have
  3.  * agreed to place such code into the public domain.  Accordingly, anyone
  4.  * who receives or obtains a copy of such source code is freely entitled to
  5.  * reproduce, use and otherwise exploit such code (including the right to
  6.  * make derivative works), at his/her own risk and expense, without any
  7.  * obligation or liability to the original copyright owners.
  8.  *
  9.  * We would appreciate (but do not require) that the following message be
  10.  * included in any derivative works:
  11.  *
  12.  * "Portions of this program were developed by Peter Broadwell, Rob Myers
  13.  * and Robin Schaufler while working in Silicon Valley."
  14.  *
  15.  * The accompanying source code files and related documentation materials
  16.  * are distributed on an "AS IS" basis, without any warranties or
  17.  * guarantees of any kind.  All implied warranties, including the implied
  18.  * warranties of merchantability and of fitness for any particular purpose,
  19.  * are expressly disclaimed.
  20.  */
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include "gl.h"
  24. #include "math.h"
  25. #include "geom.h"
  26. #include "colors.h"
  27. #include "objIds.h"
  28. #include "class.h"
  29. #include "classIds.h"
  30. #include "selectors.h"
  31. #include "mbox.h"
  32. #include "individual.h"
  33. #include "behavior.h"
  34. #include "doers.h"
  35. #include "panel.h"
  36. #include "voxel.h"
  37.  
  38. extern individual *us;
  39. extern long masterClock;
  40.  
  41. extern subscr *findvars();
  42. extern behavior chameleonTemplate;
  43. extern behavior expanderTemplate;
  44. extern behavior advancerTemplate;
  45. extern behavior surfDieTemplate;
  46. extern behavior wideyeTemplate;
  47.  
  48. Dot(p1,p2)
  49.     register point *p1, *p2;
  50. {
  51.     return (p1->x * p2->x + p1->y * p2->y + p1->z * p2->z);
  52. }
  53.  
  54. float
  55. fDot(p1,p2)
  56.     register fpoint *p1, *p2;
  57. {
  58.     return (p1->x * p2->x + p1->y * p2->y + p1->z * p2->z);
  59. }
  60.  
  61. float
  62. fiDot(p1,p2)
  63.     register fpoint *p1;
  64.     register point  *p2;
  65. {
  66.     return (p1->x * p2->x + p1->y * p2->y + p1->z * p2->z);
  67. }
  68.  
  69. float
  70. fiCrossHack(p1,p2)    /* returns only z component */
  71.     register fpoint *p1;
  72.     register point  *p2;
  73. {
  74.     return (p1->x * p2->y - p1->y * p2->x);
  75. }
  76.  
  77. normalize(p)
  78.     register fpoint *p;
  79. {
  80.     register float mag;
  81.  
  82.     mag = sqrt(fabs(p->x * p->x + p->y * p->y + p->z * p->z));
  83.     if(mag == 0.0) {
  84.     return 0;
  85.         }
  86.  
  87.     p->x = p->x / mag;
  88.     p->y = p->y / mag;
  89.     p->z = p->z / mag;
  90.     /*******/
  91.     return 1;
  92. }
  93.  
  94. vtoh(h,v)
  95.     register fpoint *h;
  96.     register point *v;
  97. {
  98.     register float mag;
  99.  
  100.     mag = sqrt((float)(abs(v->x * v->x + v->y * v->y + v->z * v->z)));
  101.     if(mag == 0.0) {
  102.     return 0;
  103.         }
  104.  
  105.     h->x = v->x / mag;
  106.     h->y = v->y / mag;
  107.     h->z = v->z / mag;
  108.     return 1;
  109. }
  110.  
  111. extern point bowlRadius;
  112.  
  113. /*
  114.  ROBS_SWIM is one of those seat of the pants heuristic algorythms
  115.  that seems to work better than the "cleaner" version peter tried.
  116.  This is an area for endless experimentation, have fun.
  117.  Also used in doerMethods.c as an inline define to keep the
  118.  Makefile simple.
  119. */
  120. #define ROBS_SWIM
  121. #ifdef ROBS_SWIM
  122.     /*
  123.      *  make the target individual swim to the next position.
  124.      */
  125.     behavior *
  126. swimTo(self, argtype, target)
  127.     behavior *self;
  128.     int argtype;
  129.     register individual *target;
  130. {
  131.     register float rspeed;
  132.     register float rad, dot, ratio = 0.0;
  133.  
  134.     rad = sqrt(fabs((float)(target->position.x * target->position.x
  135.                 + target->position.y * target->position.y )));
  136.     if(rad > bowlRadius.x) {        /* out there */
  137.     ratio = (rad/bowlRadius.x) - 1.0;
  138.     /* going out ? */
  139.     if((dot = fiDot(&target->heading,&target->position))
  140.                     > -(rad-abs(target->position.x)/8)) {
  141.         static point2df deltahead;
  142.         /* swerve witch way ? */
  143.         if(fiCrossHack(&target->heading,&target->position) > 0.0) {
  144.         deltahead.x = ratio/4.0;
  145.         } else {
  146.         deltahead.x = -ratio/6.0;
  147.         }
  148.         changeHead(target,sizeof(point2df), &deltahead);
  149.     }
  150.     }
  151.     rspeed = target->speed - 2.0 * ratio * target->speed;
  152.     target->velocity.x = target->heading.x * rspeed;
  153.     target->velocity.y = target->heading.y * rspeed;
  154.     if(fabs(target->heading.z) > 0.3) {
  155.     target->heading.z = 0.3 * sign(target->heading.z);
  156.     normalize(&target->heading);
  157.     }
  158.     target->velocity.z = target->heading.z * rspeed;
  159.     target->position.x += target->velocity.x;
  160.     target->position.y += target->velocity.y;
  161.     target->position.z += target->velocity.z;
  162.     if(target->position.z > bowlRadius.z || target->position.z < -bowlRadius.z)
  163.     target->heading.z *= -1;
  164.  
  165. /********
  166.     printf("swimTo:");
  167.     printf(" speed=%g", target->speed);
  168.     printf(" heading=%g,%g,%g", 
  169.         target->heading.x, target->heading.y, target->heading.z);
  170.     printf(" velocity=%d,%d,%d", 
  171.         target->velocity.x, target->velocity.y, target->velocity.z);
  172.     printf("\n");
  173. /********/
  174.  
  175.     return self;
  176. }
  177.     /*
  178.      *  make the target individual swim to the next position.
  179.      */
  180.     behavior *
  181. rrswimTo(self, argtype, target) behavior *self;
  182.     int argtype;
  183.     register individual *target;
  184. {
  185.     extern point bowlRadius;
  186.     register long dim = 0,*velocity,*position,*bowlsize,*maxvelocity;
  187.     int gumbyFlag = FALSE;
  188.     int abspos, minmax, bowleffect;
  189.     swerverVars *targetVars;
  190.  
  191.     if (targetVars = (swerverVars *)target->curVars) {
  192.     velocity = &target->velocity.x;
  193.     position = &target->position.x;
  194.     bowlsize = &bowlRadius.x;
  195.     maxvelocity = &targetVars->maxvelocity.x;
  196.     minmax = min(maxvelocity[0], maxvelocity[1]);
  197.  
  198.     target->velocity.x = target->heading.x * target->speed;
  199.     target->velocity.y = target->heading.y * target->speed;
  200.     target->velocity.z = target->heading.z * target->speed;
  201.  
  202.     bowleffect = (*bowlsize)-((*bowlsize) >> 2);  /* 3/4 bowl radius */
  203.         /* for each dimension:*/
  204.     for(dim = 0; dim < 3;
  205.         dim++,velocity++,position++,bowlsize++,maxvelocity++)
  206.     {
  207.         abspos = abs(*position);
  208.         if(bowleffect < abspos) {
  209.             /* going out slow */
  210.             if(abs(*velocity) <= max(10, target->speed/16)
  211.             && sign(*velocity) == sign(*position)) {
  212.             *velocity = -(*velocity);
  213.             gumbyFlag = TRUE;
  214.         } else {                    /* full speed */
  215.             *velocity = *velocity *(*bowlsize+1 - min(*bowlsize,abspos))
  216.                         / (*bowlsize - bowleffect);
  217.         }
  218.         if(! *velocity)
  219.             *velocity = -sign(*position) *
  220.                 max(10, target->speed/16);
  221.         }
  222.  
  223.             /*  keep z much smaller than x and y  */
  224.         if(dim == 2) {
  225.         *velocity = sign(*velocity) *
  226.                 min(abs(*velocity),
  227.                 min(abs(target->velocity.x),
  228.                     abs(target->velocity.y))
  229.                 * *maxvelocity / minmax);
  230.         }
  231.         *position += *velocity;
  232.     }
  233.         /* adjust heading to match possibly-changed velocity */
  234.     if(gumbyFlag) vtoh(&target->heading, &target->velocity);
  235.  
  236. /********/
  237.     printf("swimTo:");
  238.     printf(" speed=%g", target->speed);
  239.     printf(" heading=%g,%g,%g", 
  240.             target->heading.x, target->heading.y, target->heading.z);
  241.     printf(" velocity=%d,%d,%d", 
  242.             target->velocity.x, target->velocity.y, target->velocity.z);
  243.     printf("\n");
  244. /********/
  245.     }
  246.     else fprintf(stderr, "swimTo: can't find instance variables\n");
  247.  
  248.     return self;
  249. }
  250. #else /* ROBS_SWIM */
  251.     /*
  252.      *  make the target individual swim to the next position.
  253.      */
  254.     behavior *
  255. rswimTo(self, argtype, target)
  256.     behavior *self;
  257.     int argtype;
  258.     register individual *target;
  259. {
  260.     extern point bowlRadius;
  261.     register int dim = 0, *velocity, *position, *bowlsize, *maxvelocity;
  262.     int abspos, minmax;
  263.     swerverVars *targetVars;
  264.  
  265.     if (targetVars = (swerverVars *)target->curVars) {
  266.     velocity = &target->velocity.x;
  267.     position = &target->position.x;
  268.     bowlsize = &bowlRadius.x;
  269.     maxvelocity = &targetVars->maxvelocity.x;
  270.     minmax = min(maxvelocity[0], maxvelocity[1]);
  271.  
  272.     /* for each dimension:*/
  273.     for(dim = 0; dim < 3;
  274.         dim++, velocity++, position++, bowlsize++, maxvelocity++)
  275.     {
  276.         abspos = abs(*position);
  277.             /*  if position is more than halfway to side of bowl  */
  278.         if((*bowlsize) >> 1 < abspos) {
  279.             if(abs(*velocity) <= min(10,(*maxvelocity)>>4)
  280.             && sign(*velocity) == sign(*position)) {
  281.             *velocity = -(*velocity);
  282.         } else {
  283.             *velocity = (sign(*velocity) * *maxvelocity *
  284.                     ((*bowlsize) - abspos)) /
  285.                     ((*bowlsize) >> 1);
  286.         }
  287.         if(! *velocity)
  288.             *velocity = -sign(*position) *
  289.                 min(10,(*maxvelocity)>>4);
  290.         }
  291.             /*  keep z much smaller than x and y  */
  292.         if(dim == 2) {
  293.         *velocity = sign(*velocity) *
  294.                 min(abs(*velocity),
  295.                 min(abs(target->velocity.x),
  296.                     abs(target->velocity.y))
  297.                 * *maxvelocity / minmax);
  298.         }
  299.         *position += *velocity;
  300.     }
  301.     }
  302.     else printf(stderr, "swimTo: can't find instance variables\n");
  303.  
  304.     return self;
  305. }
  306. #endif /* ROBS_SWIM */
  307.  
  308. #ifdef PETERS_SWIM
  309.     /*
  310.      *  make the target individual swim to the next position.
  311.      */
  312.     behavior *
  313. pswimTo(self, argtype, target)
  314.     behavior *self;
  315.     int argtype;
  316.     register individual *target;
  317. {
  318.     float rad;
  319.     static point2df veer = { 0.0, PI/3.0, };
  320.     float sp = target->speed;
  321.     fpoint *hd = &target->heading;
  322.     point *v = &target->velocity;
  323.     point *p = &target->position;
  324.     static int sizebowl = 3000;
  325.  
  326.     v->x = sp * hd->x;
  327.     v->y = sp * hd->y;
  328.     v->z = sp * hd->z;
  329.  
  330.     p->x = v->x + p->x;
  331.     p->y = v->y + p->y;
  332.     p->z = v->z + p->z;
  333.  
  334.     rad = sqrt(fabs((float)(p->x * p->x + p->y * p->y)));
  335.  
  336. printf("rad = %g\n", rad);
  337.     if(rad > sizebowl) {
  338.     p->x += p->x * 0.9;
  339.     p->y += p->y * 0.9;
  340.     p->z += p->z * 0.9;
  341. puts("pre veer ");dumpIndiv(target);
  342.     Msg(target, NEWHEADING, sizeof(point2df), &veer);
  343.     }
  344.  
  345.  
  346. printf("0x%x at ", target);puts("swimTo end");dumpIndiv(target);
  347.     return self;
  348. }
  349. #endif /* PETERS_SWIM */
  350.  
  351. dumpIndiv(s)
  352.     individual *s;
  353. {
  354.     printf("pos = %d %d %d\n", s->position.x, s->position.y, s->position.z);
  355.     printf("vel = %d %d %d\n", s->velocity.x, s->velocity.y, s->velocity.z);
  356.     printf("head = %g %g %g\n", s->heading.x, s->heading.y, s->heading.z);
  357.     printf("speed = %g\n", s->speed);
  358. }
  359.